package com.gitee.feizns.quickstart.dict.spring.boot.autoconfigure.db.mybatis.flex;

import com.gitee.feizns.dynamic.bean.Beans;
import com.gitee.feizns.quickstart.dict.AbstractDictDepositor;
import com.gitee.feizns.quickstart.dict.DictDepositor;
import com.gitee.feizns.quickstart.dict.Entry;
import com.gitee.feizns.quickstart.dict.NothingToDoDictDepositor;
import com.gitee.feizns.quickstart.dict.Permission;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.core.util.LambdaGetter;
import com.mybatisflex.core.util.LambdaUtil;

import java.util.List;

/**
 * qk dict 存款器
 * @author feizns
 * @since 2024/12/20
 */
public class MybatisFlexQkDepositor<T extends Entry> extends AbstractDictDepositor<T> {

    /**
     * 自定义字典实体类型
     */
    private final Class<T> entityClass;

    /**
     * 密钥获取器
     */
    private final LambdaGetter<T> keyGetter;

    /**
     * Mybatis Flex QK 存款机
     * @param keyGetter 密钥获取器
     */
    public MybatisFlexQkDepositor(LambdaGetter<T> keyGetter) {
        this(keyGetter, new NothingToDoDictDepositor<>());
    }

    @SuppressWarnings("unchecked")
    public MybatisFlexQkDepositor(LambdaGetter<T> keyGetter, DictDepositor<T> delegate) {
        super(delegate);
        this.keyGetter = keyGetter;
        this.entityClass = (Class<T>) LambdaUtil.getImplClass(keyGetter);
    }

    @Override
    public DictDepositor<T> reload() {
        if ( delegate != null )
            delegate.reload();
        return this;
    }

    @Override
    public List<T> list() {
        return QueryChain.of(entityClass).list();
    }

    @Override
    public T get(String key) {
        //查询数据库是否存在
        T entry = QueryChain.of(entityClass).eq(keyGetter, key).one();
        //放置缓存
        if ( entry == null ) {
            //代理查找
            entry = delegate.get(key);
            //
            if ( entry != null )
                QueryChain.of(entityClass).baseMapper().insertOrUpdate(entry);
        }
        return entry;
    }

    @Override
    public void put(T entry) {
        T one = QueryChain.of(entityClass).eq(keyGetter, entry.getKey()).one();
        if ( one != null && one.getPermission() == Permission.ReadOnly )
            throw new UnsupportedOperationException(String.format("不支持修改只读字典[%s]", entry.getKey()));
        if ( one == null )
            one = Beans.copyProperties(entityClass, entry);
        else
            Beans.copyProperties(one, entry);
        QueryChain.of(entityClass).baseMapper().insertOrUpdate(one);
        //处理代理
        delegate.put(entry);
    }

    @Override
    public boolean exists(String key) {
        return QueryChain.of(entityClass).eq(keyGetter, key).exists();
    }

    @Override
    public T delete(String key) {
        T entry = get(key);
        if ( entry != null ) {
            if ( entry.getPermission() == Permission.ReadOnly )
                throw new UnsupportedOperationException(String.format("不支持删除只读字典[%s]", entry.getKey()));
            UpdateChain.of(entry).eq(keyGetter, key).remove();
            delegate.delete(key);
        }
        return entry;
    }

}
